/* *
 * --ライセンスについて--
 *
 * 「本ファイルの内容は Mozilla Public License Version 1.1 (「本ライセンス」)
 * の適用を受けます。
 * 本ライセンスに従わない限り本ファイルを使用することはできません。
 * 本ライセンスのコピーは http://www.mozilla.org/MPL/ から入手できます。
 *
 * 本ライセンスに基づき配布されるソフトウェアは、「現状のまま」で配布されるものであり、
 * 明示的か黙示的かを問わず、いかなる種類の保証も行われません。
 * 本ライセンス上の権利および制限を定める具体的な文言は、本ライセンスを参照してください。
 *
 * オリジナルコードおよび初期開発者は、N_H (h.10x64@gmail.com) です。
 *
 * N_H によって作成された部分の著作権表示は次のとおりです。
 *
 * Copyright (C)N_H 2012
 *
 * このファイルの内容は、上記に代えて、
 * GNU General License version2 以降 (以下 GPL とする)、
 * GNU Lesser General Public License Version 2.1 以降 (以下 LGPL とする)、
 * の条件に従って使用することも可能です。
 * この場合、このファイルの使用には上記の条項ではなく GPL または LGPL の条項が適用されます。
 * このファイルの他者による使用を GPL または LGPL の条件によってのみ許可し、
 * MPL による使用を許可したくない対象者は、上記の条項を削除することでその意思を示し、
 * 上記条項を GPL または LGPL で義務付けられている告知およびその他の条項に置き換えてください。
 * 対象者が上記の条項を削除しない場合、
 * 受領者は MPL または GPL または LGPL ライセンスのいずれによってもこのファイルを
 * 使用することができます。」
 *
 * -- License --
 *
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License。You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND、either express or implied。See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Initial Developer of the Original Code is
 *   N_H (h.10x64@gmail.com).
 *
 * Portions created by the Initial Developer are Copyright (C)N_H 2012
 * the Initial Developer。All Rights Reserved.
 *
 * Alternatively、the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL")、or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above。If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL、and not to allow others to
 * use your version of this file under the terms of the MPL、indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL。If you do not delete
 * the provisions above、a recipient may use your version of this file under
 * the terms of any one of the MPL、the GPL or the LGPL.
 *
 * */
package com.magiciansforest.audio.soundrenderer.logic.sound;

import com.magiciansforest.audio.file.wav.FormatChunk;
import com.magiciansforest.audio.file.wav.WavFile;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author N_H
 */
public class AudioOutputThread extends Thread {
    private WavFile out;
    private boolean isInterrupted = false, editing = false, adding = false;
    private List<byte[]> dataBuffer = new ArrayList<byte[]>();
    private byte[] outputBuffer = new byte[0];
    
    public AudioOutputThread(String path, FormatChunk fmt) throws IOException {
        this.out = WavFile.createReadWriteWavFile(path, fmt);
        out.seek(0);
    }

    @Override
    public void interrupt() {
        super.interrupt();
        this.isInterrupted = true;
    }

    @Override
    public void run() {
        while (!isInterrupted) {
            if (!dataBuffer.isEmpty() && !adding) {
                editing = true;
                for (byte[] data : dataBuffer) {
                    byte[] next = new byte[outputBuffer.length + data.length];
                    System.arraycopy(outputBuffer, 0, next, 0, outputBuffer.length);
                    System.arraycopy(data, 0, next, outputBuffer.length, data.length);
                    outputBuffer = next;
                }
                dataBuffer.clear();
                editing = false;
                
                if (outputBuffer.length > 1 * out.getFormatChunk().getByteRate()) {
                    try {
                        out.write(outputBuffer);
                    } catch (IOException ioe) {
                        ioe.printStackTrace();
                    } finally {
                        outputBuffer = new byte[0];
                    }
                }
            }
            try {
                sleep(100);
            } catch (InterruptedException ie) {
            }
        }
        try {
            out.write(outputBuffer);
            out.overwriteDataLength();
            out.close();
        } catch (IOException ioe) {
            
        }
    }
    
    public void add(byte[] data) {
        while (editing) {
            Thread.yield();
        }
        
        adding = true;
        dataBuffer.add(data);
        adding = false;
    }
}
